iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 9
0
自我挑戰組

零基礎成為 AI 解夢大師秘笈系列 第 9

【零基礎成為 AI 解夢大師秘笈】Day09 - Django VI

  • 分享至 

  • xImage
  •  

斜槓學習 – 零基礎成為 AI 解夢大師秘笈

前言

系列文章簡介

大家好,我們是 AI . FREE Team - 人工智慧自由團隊,這一次的鐵人賽,自由團隊將從0到1 手把手教各位讀者學會 (1)Python基礎語法 (2)Python Web 網頁開發框架 – Django (3)Python網頁爬蟲 – 周易解夢網 (4)Tensorflow AI語言模型基礎與訓練 – LSTM (5)實際部屬AI解夢模型到Web框架上。

為什麼技術要從零開始寫起

自由團隊的成立宗旨為開發AI/新科技的學習資源,提供各領域的學習者能夠跨域學習資料科學,並透過自主學習發展協槓職涯,結合智能應用到各式領域,無論是文、法、商、管、醫領域的朋友,都可以自由的學習AI技術。

資源

AI . FREE Team 讀者專屬福利 → Python Basics 免費學習資源

今日目標

  • 用 rest framework 建立 API

教學開始

在今天會進入更後端一點的世界,我們會實作出幾支 API去處理來自用戶端的特定 Request。在這邊會提到的 Requests 總共有3個, GET, POST, 和 DELETE。
Request,表示用戶透過特定的方式"請求"伺服器端做一些操作,在這兩天的會用到的例子,都會與資料庫的操作有關係。另外,如果有牽涉到回傳或是上傳的部分,我們通常都會將資料格式轉換成 JSON 的形式(與 Python 的 List 很像,基本的格式為 {"key": “value”})。像是下方的圖片,為等一下會做出來專門處理GET Request 的API所回傳的資料,為標準的 JSON 格式。
https://ithelp.ithome.com.tw/upload/images/20200924/20130712DAI4daLWbm.png

1 簡介 HttpRequest Methods

GET

  • 單純用來取得資料。
  • 例子: 取得所有學派的資料。

POST

  • 發出 Request 時,會伴隨其他參數。
  • 例子: 新增所有學派的資料,除了發 request 以外還需要伴隨新的學派的資訊。

DELETE

  • 發出 Request 刪除資料庫的特定內容,會伴隨其他參數。
  • 例子: 刪出某個古人的資料,也需要伴隨能夠古人的資訊(如 id, name)。

我們今天會使用到 Django RestFramework 這個套件,來簡潔的實現API的建立。

2 API 是什麼

在我們進入到下一步驟之前,先來探討 API 這個概念,英文全名是 Application Programming Interface,而中文翻譯是應用程式介面,使用者端不需要知道應用程式是如何運作的,使用者只需要知道該怎麼使用 API 就好了。生活中其實隨處可見 API 的例子,以買飲料為例,我們去飲料機投硬幣得到飲料。在這個動作裡面,飲料機就是這個動作的介面 (Interface),它負責接收硬幣,然後回傳飲料給使用者。類比到我們的使用情境,我們想要API 做到的事情是,接收到 Requests (GET, POST, DELETE)之後,會回傳給使用者一個他們需要的內容。

3 準備階段

安裝 package

有了 Request 和 API 的基本概念後,我們就來安裝上面提到的 rest framework 套件吧。先進入虛擬環境,然後再安裝。

$ pipenv shell
$ pipenv install djangorestframework

設定 setting.py

成功安裝之後,打開 DI_project 中的設定檔,也就是 DI_project/ settings.py,在前幾天也有提過的 INSTALLED_APPS 這個 list 結構再多加入 "rest_framework" 這個APP,所以最後會變成下面這樣。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    "demo_app.apps.DemoAppConfig",
    "rest_framework",
]

目標: 設計 API,使之處理學派資料的增刪改查 Requests

新增檔案 (demo_app/ serializers.py)
首先需要在 demo_app 內多增加一個檔案,並將它命名為 serializers.py,因為它的工作就是將一連串的 model objects (ex: 學派),序列化地轉換成 JSON 格式的資料。而檔案命名使用複數(s)呈現的理由和 urls.py、views.py 是類似的,就是因為我們會有 class 是針對 Ancient_People 做 serialize、也會有 class 是針對 School 做 serialize,所以才取名為複數型

完成上面的設定之後,我們就可以進入撰寫 API 的部分了。

4 程式撰寫

首先,為了讓 Requesets 可以順利地進行,我們先將做出 serialize 的工具做好,所以先將以下內容放進 serializers.py 內。

DI_project/ demo_app/ serializers.py

from rest_framework import serializers
from demo_app.models import School
 
class School_Serializer(serializers.ModelSerializer):
 
    class Meta:
        model = School
        fields = "__all__"

我們在這裡需要先 import rest_framework 的 serializers,然後再 import 同為 demo_app 資料夾底下的 models.py 裡面的兩個class (i.e. Ancient_People 和 School)。接著,我們看到了兩層 class 的結構,在裡面那層 Meta 的 class 必須要設定2個變數。

  • model:
    • 我們將 School (學派) assign 給此變數,就是因為我們希望這個 School_Serializer 能夠針對 School 這個 model 做序列化。
  • fields:
    • 我們將此變數設定為 "all",表示我們希望對 School 內所有的欄位都做序列化。待會我們看到成果的時候就會實際的看到完整資料的回傳。

在有上面 serializers.py 的幫助下,等等的操作就會變得相當容易。在今天我們會先完成 查(GET)這部分的API,而在明天則會依照新增(POST)、修改(還是POST)、刪除(DELETE)的順序完成。

5 查(GET)

這裡我們寫3種

  1. 列出所有預計完成的API
  2. 列出所有的學派資料
  3. 列出特定學派的資料

Views

開啟 demo_app/ views.py,將以下內容加入。

from rest_framework.decorators import api_view
from rest_framework.response import Response
from demo_app.serializers import School_Serializer
 
@api_view(['GET'])
def api_overview(request):
    api_urls = {
        'Schools List':'/school_list',
        'School Detail View':'/school_detail/<int:id>',
        'School Create':'/school_create',
        'School Update':'/school_update/<int:id>',
        'School Delete':'/task-delete/<int:id>'
    }
    return Response(api_urls)
    
@api_view(['GET'])
def school_list(request):
    schools = School.objects.all()
    serializer = School_Serializer(schools, many=True)
    return Response(serializer.data)
 
@api_view(['GET'])
def school_detail(request, id):
    one_school = School.objects.get(id=id)
    serializer = School_Serializer(one_school, many=False)
    return Response(serializer.data)

首先我們先看 import 的部分,這次我們從 rest_framework 的方法中 import 了 api_viewResponse
api_view 在這邊可以設定我們的 API 支援什麼樣的 Request,以目前上方有的 API 為例,全部都是只有支援 GET 類型的 Request。另外,我們也有 import demo_app.serializers,因為我們馬上就會在這個 views.py 馬上就使用到了(i.e. School_Serializer)。

api_overview 這支API內我們一共列了5個待開發的API,大家可以注意到,我們在這邊有刻意的把資料的結構換成 JSON 的形式,也就是 { "key1": “value1”, “key2”: “value2”, ...},必須要這樣才能透過來自 rest_framework 的 Response 方法將資料傳給請求方

接著我們看最下面那支 API (i.e. school_detail),這支有懂,那上面那支就一定沒有問題了! 我們在這裡可以看到 school_detail除了接收 HttpRequest 以外,還有接收 id 這個變數,這是從 url pass 進來的,我們需要這個 id 將特定的 Shcool object 取出來。(這裡算是重複了 urls.py, views.py 交互的概念)

接下來我們實體化了 School_Serializer 這個 class,想要實體化就需要提供兩個參數,一個是學派的 Object (i.e. 上面的 one_school),另一個則是 many 的設定,如果是 False,那就表示我們只會 serialize 一個學派Object;如果是 True 的話,則表示我們預計會 serialize 不只一個學派Object,這邊的使用情境可以參考 school_list 這支API。

Urls

處理完 view 之後,我們再來把 url 也設計好。
開啟 demo_app/ urls.py,並將 urlpatterns 調整的與下方一致。在這邊,我們一起將其他尚未完成,但預計會完成的 path 也一併加入。(就是註解起來的部分)

urlpatterns = [
    path("Confucianism/<int:id>", views.confucianism_detail, name="confucianism"),
    path("Taoism/<int:id>", views.taoism_detail, name="taosim"),
    # 以下為新增的內容
    path("", views.api_overview, name="api_overview"),
    path("school_list", views.school_list, name="school_list"),
    path("school_detail/<int:id>", views.school_detail, name="school_detail"),
    #path("school_create", views.school_create, name="school_create"),
    #path("school_update/<int:id>", views.school_update, name="school_update"),
    #path("school_delete/<int:id>", views.school_delete, name="school_delete")
]

6 成果

至此,我們就算是階段性的完成了 GET Request 的API了,將 server run 起來。

$ python manage.py runserver

開啟瀏覽器,並搜尋以下 url,在這邊同時也呈現我看到的畫面。

  1. 對應到 name = api_overview 的 url: http://127.0.0.1:8000/demo_app/
    https://ithelp.ithome.com.tw/upload/images/20200924/20130712jeYWPU62AS.png

  2. 對應到 name = school_list 的 url: http://127.0.0.1:8000/demo_app/school_list
    https://ithelp.ithome.com.tw/upload/images/20200924/20130712JTZBe4nbuL.png

  3. 對應到 name = school_detail/int:id 的 url: http://127.0.0.1:8000/demo_app/school_detail/7
    Note: 這邊大家的 id 數字可能會不一樣喔,可以看看大家在上面的 name = school_list 有列出來的學派 id 為何,像我就是在 school_list 看到7,所以這邊的 school_detail 才用7。
    https://ithelp.ithome.com.tw/upload/images/20200924/20130712kUsAEuMDTs.png

有成功執行的各位,可以看在對應的URL裡看到有被自動生成的介面(此為今天下載的套件 Rest framework 產生的)。伴隨著回傳JSON型式的結果,也可以看到其他相關的資訊。

以(上圖) School Detail 為例的話:

  • 請求內容: GET /demo_app/school_detail/7
  • 回傳資訊
    • 狀態: HTTP 200 OK (表示成功 request,也有成功得到 回傳值。)
    • 其他相關的回傳值...
    • JSON Data

7 邁向 AI 解夢大師 - 第九天

今天提到了 API 和 Request 的基本概念,透過 Serializer 的協助,我們很快速的將針對 GET Request 的 API 建立起來了。在明天,我們會用兩種請求(一個是 POST,另一個則是 DELETE) 實作出能夠讓使用者 新增、修改、和刪除 的API。

8 參考連結

想更深入認識 AI . FREE Team ?

自由團隊 官方網站:https://aifreeblog.herokuapp.com/
自由團隊 Github:https://github.com/AI-FREE-Team/
自由團隊 粉絲專頁:https://www.facebook.com/AI.Free.Team/
自由團隊 IG:https://www.instagram.com/aifreeteam/
自由團隊 Youtube:https://www.youtube.com/channel/UCjw6Kuw3kwM_il39NTBJVTg/

文章同步發布於:自由團隊部落格
(想看更多文章?學習更多AI知識?敬請鎖定自由團隊的頻道!)


上一篇
【零基礎成為 AI 解夢大師秘笈】Day08 - Django V
下一篇
【零基礎成為 AI 解夢大師秘笈】Day10 - Django VII
系列文
零基礎成為 AI 解夢大師秘笈30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言